using System.Windows.Browser;
using System.Windows.Threading;

namespace HtmlUtilities
{
    public interface IScriptObject
    {
        bool CheckAccess();
        T ConvertTo<T>();
        Dispatcher Dispatcher { get; }
        object GetProperty(int index);
        object GetProperty(string name);
        object Invoke(string name, params object[] args);
        object InvokeSelf(params object[] args);
        object ManagedObject { get; }
        void SetProperty(int index, object value);
        void SetProperty(string name, object value);
    }

    internal class ScriptObjectWrapper : IScriptObject
    {
        private readonly ScriptObject _scriptObject;

        public ScriptObjectWrapper(ScriptObject scriptObject)
        {
            _scriptObject = scriptObject;
        }

        internal ScriptObject ScriptObject { get { return _scriptObject; } }

        public bool CheckAccess()
        {
            return _scriptObject.CheckAccess();
        }

        public T ConvertTo<T>()
        {
            return _scriptObject.ConvertTo<T>();
        }

        public Dispatcher Dispatcher
        {
            get { return _scriptObject.Dispatcher; }
        }

        public object GetProperty(int index)
        {
            return ReturnObject(_scriptObject.GetProperty(index));
        }

        public object GetProperty(string name)
        {
            return ReturnObject(_scriptObject.GetProperty(name));
        }

        private static object ReturnObject(object value)
        {
            if (value is ScriptObject)
                return ScriptObjectFactory.GetScriptObject(value as ScriptObject);

            return value;
        }

        public object Invoke(string name, params object[] args)
        {
            return ReturnObject(_scriptObject.Invoke(name, args));
        }

        public object InvokeSelf(params object[] args)
        {
            return ReturnObject(_scriptObject.InvokeSelf(args));
        }

        public object ManagedObject
        {
            get { return ReturnObject(_scriptObject.ManagedObject); }
        }

        public void SetProperty(int index, object value)
        {
            _scriptObject.SetProperty(index, value);
        }

        public void SetProperty(string name, object value)
        {
           _scriptObject.SetProperty(name, value);
        }
    }
}